package com.itany.nmms.service.impl;

import com.itany.mvc.util.CommonsMultipartFile;
import com.itany.nmms.constant.DictConstant;
import com.itany.nmms.dao.ProductMapper;
import com.itany.nmms.dao.SequenceMapper;
import com.itany.nmms.entity.Product;
import com.itany.nmms.entity.ProductExample;
import com.itany.nmms.entity.Sequence;
import com.itany.nmms.entity.SequenceExample;
import com.itany.nmms.exception.FileuploadErrorException;
import com.itany.nmms.exception.ProductExistException;
import com.itany.nmms.exception.RequestParameterErrorException;
import com.itany.nmms.factory.ObjectFactory;
import com.itany.nmms.service.ProductService;
import com.itany.nmms.util.ParameterUtil;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @Author:石小俊
 * @Date:2023/1/5 15:06
 * @Version:1.0-SNAPSHOT
 * @Description:
 */
public class ProductServiceImpl implements ProductService {
    @Override
    public void addProduct(String name, String price, List<CommonsMultipartFile> files, String typeId, HttpSession session) throws RequestParameterErrorException, ProductExistException, FileuploadErrorException {
        ProductMapper productMapper = (ProductMapper) ObjectFactory.getObject("productMapper");
        SequenceMapper sequenceMapper = (SequenceMapper) ObjectFactory.getObject("sequenceMapper");
        if(ParameterUtil.isNull(name) || ParameterUtil.isNull(price) || ParameterUtil.isNull(typeId) || files.isEmpty()){
            throw new RequestParameterErrorException("请求参数有误");
        }

        // 当前商品图片只有一张
        // 取出集合中的那一张图片
        CommonsMultipartFile file = files.get(0);
        if(file.isEmpty()){
            throw new RequestParameterErrorException("上传的文件不能为空");
        }

        // 同一种类型的商品名称不能重复
        ProductExample example = new ProductExample();
        example.or()
                .andNameEqualTo(name)
                .andProductTypeIdEqualTo(Integer.parseInt(typeId));
        List<Product> products = productMapper.selectByExample(example);
        if(!products.isEmpty()){
            throw new ProductExistException("该类型的商品已经存在");
        }

        // 准备一个商品对象,用于执行添加操作
        Product product = new Product();
        product.setName(name);
        product.setPrice(Double.parseDouble(price));
        product.setProductTypeId(Integer.parseInt(typeId));

        // 生成商品编号
        // 编号由三部分组成:前缀、日期、序列号
        // 前缀在常量接口中已经定义,日期使用当天的年月日的值
        // 对于序列号进行处理
        // 根据前缀在序列号表中进行查询
        SequenceExample sequenceExample = new SequenceExample();
        sequenceExample.or()
                .andNameEqualTo(DictConstant.PRODUCT_NO_PREFIX);
        List<Sequence> sequences = sequenceMapper.selectByExample(sequenceExample);
        if(sequences.isEmpty()){
            // 如果没有查询到对应的序列号数据
            // 则说明尚未生成过序列号
            // 创建一个初始的序列号数据
            Sequence sequence = new Sequence();
            sequence.setName(DictConstant.PRODUCT_NO_PREFIX);
            sequence.setValue(DictConstant.PRODUCT_NO_SEQUENCE_INIT_VALUE);
            // 执行保存操作
            sequenceMapper.insertSelective(sequence);
            // 生成对应的商品编号
            product.setProductNo(DictConstant.PRODUCT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        } else{
            // 如果查询到对应的序列号数据了
            // 则说明已经生成过对应的序列号
            // 此时查询到的数据有且仅有一条
            // 此时取出对应的序列号数据
            Sequence sequence = sequences.get(0);
            // 判断当前的序列号的值是否达到了最大值
            if(DictConstant.PRODUCT_NO_SEQUENCE_MAX_VALUE.equals(sequence.getValue())){
                // 如果序列号的值达到了最大值
                // 则下一个值为初始值
                sequence.setValue(DictConstant.PRODUCT_NO_SEQUENCE_INIT_VALUE);
            } else{
                // 如果序列号的值尚未达到最大值
                // 则其值在原有值的基础上+1
                // 保持序列号数据的格式不变
                sequence.setValue(ParameterUtil.nextValue(sequence.getValue()));
            }
            // 执行修改操作
            sequenceMapper.updateByPrimaryKeySelective(sequence);

            // 生成对应的商品编号
            product.setProductNo(DictConstant.PRODUCT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        }


        // 上传商品图片
        // 在服务器根目录创建一个目录专门存放所有的商品图片
        // 在该目录中每天创建一个以年月日命名的子目录
        // 所有图片存放在对应的子目录中

        // 获取需要存放的图片相对于服务器根目录的地址
        // 该地址用于保存到数据库中
        String path = DictConstant.PRODUCT_IMAGE_ROOT_FOLDER+new SimpleDateFormat("yyyyMMdd").format(new Date());

        // 获取需要存放图片的目录绝对地址
        String cp = session.getServletContext().getRealPath(path);
        // 创建对应的目录
        File f = new File(cp);
        f.mkdirs();
        String fileName = file.getOriginalFilename();
        // 为所有的图片名添加一个毫秒数的后缀
        fileName = fileName.substring(0,fileName.lastIndexOf("."))+"-"+new Date().getTime()+fileName.substring(fileName.lastIndexOf("."));

        // 设置商品图片的值,其值为相对路径+文件名
        product.setImage(path+"/"+fileName);

        try {
            // 添加商品
            productMapper.insertSelective(product);
            // 上传文件
            file.transferTo(new File(cp,fileName));
        } catch (Exception e) {
            e.printStackTrace();
            throw new FileuploadErrorException("上传商品图片出错");
        }

    }
}
